package cn.starlightsoftware.sherly.service.basic;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.starlightsoftware.sherly.controller.admin.basic.vo.BasicDetailRespVO;
import cn.starlightsoftware.sherly.controller.admin.permission.vo.PermissionRespVO;
import cn.starlightsoftware.sherly.controller.admin.user.vo.UserRespVO;
import cn.starlightsoftware.sherly.convertor.PermissionConvertor;
import cn.starlightsoftware.sherly.db.mysql.permission.PermissionMapper;
import cn.starlightsoftware.sherly.db.mysql.permission.RoleMapper;
import cn.starlightsoftware.sherly.db.mysql.permission.RolePermissionMapper;
import cn.starlightsoftware.sherly.db.mysql.permission.UserRoleMapper;
import cn.starlightsoftware.sherly.db.mysql.user.UserMapper;
import cn.starlightsoftware.sherly.db.model.permission.PermissionDO;
import cn.starlightsoftware.sherly.db.model.permission.RoleDO;
import cn.starlightsoftware.sherly.db.model.permission.RolePermissionDO;
import cn.starlightsoftware.sherly.db.model.permission.UserRoleDO;
import cn.starlightsoftware.sherly.db.model.user.UserDO;
import cn.starlightsoftware.sherly.security.utils.SecurityUtil;
import cn.starlightsoftware.sherly.utils.StreamUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author 谷子毅
 * @date 2024/5/13
 */
@Service
public class BasicServiceImpl implements BasicService{

    @Resource
    private UserMapper userMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Resource
    private PermissionMapper permissionMapper;

    @Override
    public BasicDetailRespVO detail() {
        String userId = SecurityUtil.getLoginUserId();

        UserDO user = userMapper.selectById(userId);

        List<UserRoleDO> userRoleList = userRoleMapper.selectList(UserRoleDO::getUserId, userId);
        Set<String> roleCodes = new HashSet<>();
        Set<String> permissionCodes = new HashSet<>();
        List<PermissionDO> permissions = new ArrayList<>();

        if (CollectionUtil.isNotEmpty(userRoleList)) {
            Set<String> roleIds = StreamUtil.toSet(userRoleList, UserRoleDO::getRoleId);

            List<RoleDO> roles = roleMapper.selectBatchIds(roleIds);
            if (CollectionUtil.isNotEmpty(roles)) {
                roleCodes.addAll(StreamUtil.toSet(roles, RoleDO::getRoleCode));

                List<RolePermissionDO> rolePermissionList = rolePermissionMapper.selectList(RolePermissionDO::getRoleId, roleIds);
                if (CollectionUtil.isNotEmpty(rolePermissionList)) {
                    Set<String> permissionIds = StreamUtil.toSet(rolePermissionList, RolePermissionDO::getPermissionId);

                    permissions = permissionMapper.selectBatchIds(permissionIds);
                    if (CollectionUtil.isNotEmpty(permissions)) {
                        permissionCodes.addAll(StreamUtil.toSet(permissions, PermissionDO::getPermissionCode));
                    }
                }
            }
        }

        List<PermissionRespVO> menus = PermissionConvertor.buildTree(permissions);

        Set<String> scopes = new HashSet<>();
        roleCodes.forEach(roleCode -> scopes.add("ROLE_" + roleCode));
        scopes.addAll(permissionCodes);

        return new BasicDetailRespVO()
                .setUser(BeanUtil.copyProperties(user, UserRespVO.class))
                .setMenus(menus)
                .setScopes(scopes);
    }

}
